﻿using System;
using System.Collections.Generic;
using System.IO;
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio.SharePoint;
using Microsoft.VisualStudio.Shell;

namespace PS_WSSDeploy_Package.Application
{
    public class DTEManager
    {
        private OutputWindow applicationOutputWindow;
        private OutputWindowPane buildWindow;
        private static readonly object lockFlag = new object();
        private static DTEManager instance;

        public DTE2 Application { get; set; }

        private DTEManager(DTE2 application)
        {
            Application = application;
        }

        public static DTEManager Instance
        {
            get
            {
                lock (lockFlag)
                {
                    if (instance == null)
                    {
                        var dte = GetDTE2();
                        instance = new DTEManager(dte);
                    }
                    return instance;
                }
            }
        }

        static private DTE2 GetDTE2()
        {
            var dte = (DTE)Package.GetGlobalService(typeof(DTE));
            var dte2 = dte as DTE2;
            return dte2;
        }

        public OutputWindow ApplicationOutputWindow
        {
            get
            {
                return
                    applicationOutputWindow
                    ?? (applicationOutputWindow = Application.ToolWindows.OutputWindow);
            }
            set { applicationOutputWindow = value; }
        }

        public OutputWindowPane BuildWindow
        {
            get
            {
                return
                    buildWindow
                    ?? (buildWindow = ApplicationOutputWindow.OutputWindowPanes.Item("Build"));
            }
            set { buildWindow = value; }
        }

        public SelectedItem FirstSelectedItem
        {
            get
            {
                SelectedItem item = null;
                if (Application.SelectedItems.Count > 0)
                {
                    item = Application.SelectedItems.Item(1);
                }
                return item;
            }
        }

        public Project SelectedProject
        {
            get
            {
                return GetProject(FirstSelectedItem);
            }
        }

        private Project GetProject(SelectedItem item)
        {
            Project result = null;
            if (item != null)
            {
                if (item.ProjectItem != null)
                {
                    result = item.ProjectItem.ContainingProject;
                }
                else
                {
                    result = item.Project;
                }
            }
            return result;
        }

        public string SolutionPath
        {
            get
            {
                return GetSolutionPath();
            }
        }

        private string GetSolutionPath()
        {
            return (Application.Solution != null) ?
                Path.GetDirectoryName(Application.Solution.FullName) : string.Empty;
        }

        public Project ActiveProject
        {
            get
            {
                return GetActiveProject();
            }
        }

        private Project GetActiveProject()
        {
            Project project = null;
            var ar = (Array)Application.ActiveSolutionProjects;
            if (ar.Length > 0)
            {
                project = (Project)ar.GetValue(0);
            }
            return project;
        }

        public Project WorkedProject
        {
            get
            {
                return GetWorkedProject();
            }
        }

        public ProjectItem WorkedProjectItem
        {
            get
            {
                return GetWorkedProjectItem();
            }
        }

        private Project GetWorkedProject()
        {
            string activeWindowCaption = Application.ActiveWindow.Caption;
            if (activeWindowCaption.StartsWith("Solution Explorer"))
            {
                return GetActiveProject();
            }

            var activeDoc = Application.ActiveDocument;
            if (activeDoc != null)
            {
                return activeDoc.ProjectItem.ContainingProject;
            }
            return GetActiveProject();
        }

        private ProjectItem GetWorkedProjectItem()
        {
            string activeWindowCaption = Application.ActiveWindow.Caption;
            if (activeWindowCaption.StartsWith("Solution Explorer"))
            {
                return GetSelectedProjectItem();
            }
            var activeDoc = Application.ActiveDocument;
            if (activeDoc != null)
            {
                return activeDoc.ProjectItem;
            }
            return GetSelectedProjectItem();
        }

        private ProjectItem GetSelectedProjectItem()
        {
            ProjectItem projectItem = null;
            if (Application.SelectedItems.Count > 0)
            {
                SelectedItem si = Application.SelectedItems.Item(1);
                projectItem = si.ProjectItem;
            }
            return projectItem;
        }

        public List<ProjectItem> GetSelectedProjectItems()
        {
            var ret = new List<ProjectItem>();

            for (var i = 1; i <= Application.SelectedItems.Count; ++i)
            {
                var si = Application.SelectedItems.Item(i);
                ret.Add(si.ProjectItem);
            }
            return ret;
        }

        public IEnumerable<Project> GetAllProjectOfSolution()
        {
            if (Application == null || Application.Solution == null || Application.Solution.Projects == null)
            {
                yield break;
            }
            foreach (Project p in Application.Solution.Projects)
            {
                yield return p;
            }
        }

        public void StartNewBuildWindow()
        {
            //BuildWindow.Clear();
            BuildWindow.Activate();
            ApplicationOutputWindow.Parent.Activate();
        }

        public void WriteBuildWindow(string text)
        {
            if (Application != null)
            {
                BuildWindow.OutputString(text + Environment.NewLine);
            }
        }

        public void StatusBar(string message)
        {
            if (Application != null)
            {
                Application.StatusBar.Text = message;
            }
        }

        public void WriteBuildAndStatusBar(string message)
        {
            WriteBuildWindow(message);
            StatusBar(message);
        }
    }
}
